package com.gui;

import java.util.ArrayList;
import java.util.List;

import org.teleal.cling.android.AndroidUpnpService;
import org.teleal.cling.controlpoint.ActionCallback;
import org.teleal.cling.model.action.ActionInvocation;
import org.teleal.cling.model.message.UpnpResponse;
import org.teleal.cling.model.meta.LocalDevice;
import org.teleal.cling.model.meta.RemoteDevice;
import org.teleal.cling.model.meta.Service;
import org.teleal.cling.model.types.ServiceId;
import org.teleal.cling.model.types.UDAServiceId;
import org.teleal.cling.model.types.UnsignedIntegerFourBytes;
import org.teleal.cling.registry.DefaultRegistryListener;
import org.teleal.cling.registry.Registry;
import org.teleal.cling.support.model.DIDLContent;
import org.teleal.cling.support.model.container.Container;
import org.teleal.cling.support.model.item.Item;
import org.teleal.cling.support.contentdirectory.DIDLParser;
import android.util.Log;
import android.widget.Toast;

public class BrowseRegistryListener extends DefaultRegistryListener {
	
	private static final String TAG = BrowseRegistryListener.class.getName();
	ServiceId serviceId = new UDAServiceId("AVTransport");	
	AndroidUpnpService mService = null;
	DLNAActivity parrentActivity;
	Service remoteDMR = null;
	Service DMSService = null;
	List<RemoteDevice> DMSServerList = new ArrayList<RemoteDevice>();
	
	boolean bLoading = true;

	boolean getLoadingState() {
		return bLoading;
	}

	public void setService(AndroidUpnpService service) {
		mService = service;
	}

	@Override
	public void remoteDeviceDiscoveryStarted(Registry registry,
			RemoteDevice device) {
		Log.i(TAG, "DiscoveryStarted ... ");
	}

	@Override
	public void remoteDeviceDiscoveryFailed(Registry registry,
			final RemoteDevice device, final Exception ex) {
		Log.i(TAG, "DiscoveryFail ...");
	}

	@Override
	public void remoteDeviceAdded(Registry registry, RemoteDevice device) {
		Log.i(TAG, "DeviceAdded ...");
		for (Service service : device.getServices()) {
			
			if (service.getServiceType().getType().equals("ContentDirectory")) {				
				DMSService = service;				
				DMSServerList.add(device);				
				break;				
//				browsefile("0");
			}
		}
	}

	public List<RemoteDevice> showDMSServer(){
		Log.i(TAG, "showDMSServerList");
		if (DMSServerList.size() > 0){
			for (int i = 0; i < DMSServerList.size() ; i++){
				Log.i(TAG, DMSServerList.get(i).getDisplayString());
			}
		}
		return DMSServerList;
	}
		
	@Override
	public void remoteDeviceRemoved(Registry registry, RemoteDevice device) {
		Log.i(TAG, "DeviceRemoved");
	}

	@Override
	public void localDeviceAdded(Registry registry, LocalDevice device) {
		Log.i(TAG, "LocalDeviceAdded");

	}

	@Override
	public void localDeviceRemoved(Registry registry, LocalDevice device) {
		Log.i(TAG, "LocalDeviceRemoved");

	}
		
	public void browsefile(final String objectId) {
		if (mService != null && DMSService != null) {
			ActionInvocation actionInvocation = new BrowseActionInvocation(
					DMSService, objectId);
			
			mService.getControlPoint().execute( new ActionCallback(actionInvocation) {
						
						@Override
						public void failure(ActionInvocation actionInvocation,
								UpnpResponse reponse, String error) {
							Log.e(TAG, "Fail browse action");
							Log.e(TAG, reponse.getStatusMessage());
							Log.e(TAG, reponse.getResponseDetails());
							Log.e(TAG, error);							
						}

						@Override
						public void success(ActionInvocation actionInvocation) {
							Log.i(TAG, "Successful browse action, reading output argument values");
							
							DIDLParser parser = new DIDLParser();
							DIDLContent content = null;
							try {
								content = parser.parse(actionInvocation.getOutput("Result").getValue().toString());
							} catch (Exception e) {
								e.printStackTrace();
							}

							if (content != null) {

								Log.i(TAG, "Containers size: " + content.getContainers().size());
								for (Container container : content.getContainers()){
									Log.i(TAG, "container.getTitle(): " + container.getTitle());
									Log.i(TAG, "container.getId(): " + container.getId());
								}
								Log.i(TAG, "Item size: " + content.getItems().size());
								for (Item item : content.getItems()){
									Log.i(TAG, "item.getTitle(): " + item.getTitle());
									Log.i(TAG, "item.getId(): " + item.getId());
								}
							}							
						}
					});
		}
	}

	public void showToast(final String message) {
		parrentActivity.runOnUiThread(new Runnable() {

			@Override
			public void run() {
				Toast.makeText(parrentActivity, message, Toast.LENGTH_SHORT)
						.show();
			}
		});
	}

	public void play(String instanceID) {
		if (remoteDMR != null && mService != null) {
			ActionInvocation actionInvocation = new Play(remoteDMR, instanceID);

			mService.getControlPoint().execute(
					new ActionCallback(actionInvocation) {

						@Override
						public void failure(ActionInvocation arg0,
								UpnpResponse arg1, String arg2) {
							Log.e(TAG, "play fail" + arg0.getFailure());
							bLoading = false;
						}

						@Override
						public void success(ActionInvocation arg0) {
							Log.i(TAG, "play success");
							bLoading = false;
//							parrentActivity.playComplete();
						}
					});
		}
	}

	public void pause(String instanceID) {
		if (remoteDMR != null && mService != null) {
			ActionInvocation actionInvocation = new Pause(remoteDMR, instanceID);

			mService.getControlPoint().execute(
					new ActionCallback(actionInvocation) {

						@Override
						public void failure(ActionInvocation arg0,
								UpnpResponse arg1, String arg2) {
							Log.e(TAG, "pause failed" + arg0.getFailure());
//							bLoading = false;
						}

						@Override
						public void success(ActionInvocation arg0) {
							Log.i(TAG, "pause successful");
							bLoading = false;
//							parrentActivity.pauseComplete();
						}
					});
		}
	}

	public void stop() {
		if (remoteDMR != null && mService != null) {
			ActionInvocation<Service> actionInvocation = new Stop(remoteDMR);
			mService.getControlPoint().execute(
					new ActionCallback(actionInvocation) {

						@Override
						public void failure(ActionInvocation arg0,
								UpnpResponse arg1, String arg2) {
							Log.e(TAG, arg0.getAction().getName() + " failed");
//							bLoading = false;
						}

						@Override
						public void success(ActionInvocation arg0) {
							Log.i(TAG, arg0.getAction().getName() + " success");
//							bLoading = false;
//							parrentActivity.stopComplete();
						}
					});
		}
	}

	class Play extends ActionInvocation {
		public Play(Service service, String instanceID) {
			super(service.getAction("Play"));
			try {
//				bLoading = true;
				setInput("InstanceID", new UnsignedIntegerFourBytes(instanceID));
				setInput("Speed", "1");
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
	}

	class Pause extends ActionInvocation {
		public Pause(Service service, String instanceID) {
			super(service.getAction("Pause"));
			try {
//				bLoading = true;
				setInput("InstanceID", new UnsignedIntegerFourBytes(instanceID));
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
	}

	class Stop extends ActionInvocation {
		public Stop(Service service) {
			super(service.getAction("Stop"));
			try {
//				bLoading = true;
				setInput("InstanceID", new UnsignedIntegerFourBytes(0));
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
	}

	public class BrowseActionInvocation extends ActionInvocation {
		
		public BrowseActionInvocation(Service service, String objectID) {
			super(service.getAction("Browse"));
			if (objectID != null) {
				setInput("ObjectID", objectID);
			} else {
				setInput("ObjectID", "0");
			}
			setInput("BrowseFlag", "BrowseDirectChildren");
			setInput("Filter", "*");
			setInput("StartingIndex", new UnsignedIntegerFourBytes(0));
			setInput("RequestedCount", new UnsignedIntegerFourBytes(999));
		}
	}
}